/**
 * 
 */
package com.zznode.client.wlanpolling.test;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.achartengine.ChartFactory;
import org.achartengine.GraphicalView;
import org.achartengine.chart.PointStyle;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import org.achartengine.renderer.XYMultipleSeriesRenderer;
import org.achartengine.renderer.XYSeriesRenderer;

import android.content.Context;
import android.graphics.Color;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.LinearLayout.LayoutParams;

import com.zznode.client.wlanpolling.R;
import com.zznode.client.wlanpolling.WLanContext;
import com.zznode.client.wlanpolling.model.WirelessEvnInfo;
import com.zznode.client.wlanpolling.service.Wifi;
import com.zznode.client.wlanpolling.service.WifiGroup;
import com.zznode.client.wlanpolling.utils.ColorUtils;
import com.zznode.client.wlanpolling.utils.GaussArithmetic;
import com.zznode.client.wlanpolling.utils.NetworkUtils;
import com.zznode.client.wlanpolling.widget.SignalView;

/**
 * @author Bean
 * 
 */
public class WirelessEnvAdaptor extends BaseExpandableListAdapter {
	private LayoutInflater mInflater = null;
	private Context context;
	private Wifi currentWifi;
	
	private WirelessEvnInfo wirelessEvnInfo;

	private List<Wifi> sameFrequencyInterference;
	private List<Wifi> nearbyFrequencyInterference;
	
	private GraphicalView chartView;
	private View chartContainerView;
	private XYMultipleSeriesRenderer renderer = new XYMultipleSeriesRenderer();
	private XYMultipleSeriesDataset dataset;

	public WirelessEnvAdaptor(Context ctx, WirelessEvnInfo wirelessEvnIfno,
			WLanContext wlanContext, List<Wifi> wifis) {
		this.context = ctx;
		mInflater = (LayoutInflater) ctx
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		this.wirelessEvnInfo = wirelessEvnIfno;
		currentWifi = wlanContext.getCurrentWifi();
		
		// 获取同频干扰信息
		sameFrequencyInterference = calSameFrequencyInterference(currentWifi,
				wifis);
		// 获取邻频干扰信息
		nearbyFrequencyInterference = calNearbyFrequencyInterference(currentWifi, wifis);
		
		chartContainerView = initGraphicView();
	}

	public List<Wifi> getSameFrequencyInterference() {
		return sameFrequencyInterference;
	}

	public List<Wifi> getNearbyFrequencyInterference() {
		return nearbyFrequencyInterference;
	}
	
	public void setWifiList(List<Wifi> wifis) {
		// 获取同频干扰信息
		sameFrequencyInterference = calSameFrequencyInterference(currentWifi,
				wifis);
		// 获取邻频干扰信息
		nearbyFrequencyInterference = calNearbyFrequencyInterference(currentWifi, wifis);
		
		notifyDataSetChanged();
	}
	
	private List<Wifi> calSameFrequencyInterference(Wifi wifi,
			List<Wifi> wifis) {
		
		List<Wifi> result = new ArrayList<Wifi>();
		
		for(Wifi otherWifi : wifis) {
			if(otherWifi.getFrequency() == wifi.getFrequency() &&
					otherWifi.isSelected() == false) {
				result.add(otherWifi);
			}
		}
		
		return result;
	}

	private List<Wifi> calNearbyFrequencyInterference(Wifi wifi,
			List<Wifi> wifis) {
		List<Wifi> result = new ArrayList<Wifi>();
		
		Set<Integer> disturbs = NetworkUtils.getNeighbourDisturbs(wifi.getFrequency());
		
		for(Wifi otherWifi : wifis) {
			if(otherWifi.getFrequency() == wifi.getFrequency()) {
				continue;
			}
			
			int channel = NetworkUtils.getChannel(otherWifi.getFrequency());
			if(disturbs.contains(channel)) {
				result.add(otherWifi);
			}
		}
		
		return result;
	}

	@Override
	public Object getChild(int groupPosition, int childPosition) {
		if (groupPosition == 0) {
			return "当前AP无线配置";
		} else if (groupPosition == 1) {
			return "干扰图";
		} else if (groupPosition == 2) {
			return "同频干扰";
		} else if(groupPosition == 3) {
			return "邻频干扰";
		}
		
		return "";
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return childPosition;
	}

	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		View view = null;
		if (groupPosition == 0) {
			if (view == null) {
				view = mInflater.inflate(R.layout.wirellessenvinfo, null);
			}
			
			TextView tv = (TextView) (view.findViewById(R.id.wireless_channel));
			tv.setText(wirelessEvnInfo.getWirelessChannel());
			tv = (TextView) (view.findViewById(R.id.wireless_mode));
			tv.setText(wirelessEvnInfo.getWirelessMode());
			tv = (TextView) (view.findViewById(R.id.wireless_power));
			tv.setText(wirelessEvnInfo.getWirelessPower());
			tv = (TextView)(view.findViewById(R.id.wireless_vlanid));
			tv.setText(wirelessEvnInfo.getWirelessVlanid());
			tv = (TextView) (view.findViewById(R.id.wireless_relativeclient));
			tv.setText(wirelessEvnInfo.getWirelessRelativeclient());
			//beacon
			tv = (TextView) (view.findViewById(R.id.beacon));
			tv.setText(wirelessEvnInfo.getBeacon());
			//信道自动分配开关
			tv = (TextView)(view.findViewById(R.id.radioChannel_AutoSelect_enable));
			tv.setText(wirelessEvnInfo.getRadioChannel_AutoSelect_enable());
		} else if (groupPosition == 2 || groupPosition == 3) {
			if (view == null) {
				view = mInflater.inflate(R.layout.wireless_inferenceinfo, null);
			}
			Wifi wifi = null;
			if (groupPosition == 2) {
				wifi = sameFrequencyInterference.get(childPosition);
			} else {
				wifi = nearbyFrequencyInterference.get(childPosition);
			}
			
			TextView tv = (TextView) (view.findViewById(R.id.txt_apname));
			tv.setText(wifi.getSSID());
			tv = (TextView) (view.findViewById(R.id.txt_bssid));
			tv.setText(wifi.getBSSID());
			tv = (TextView) (view.findViewById(R.id.txt_authentication));
			tv.setText(wifi.getCapabilities().toString());
			tv = (TextView) (view.findViewById(R.id.txt_channel));
			tv.setText(NetworkUtils.getChannel(wifi.getFrequency()) + "");
			tv = (TextView) (view.findViewById(R.id.txt_frequence));
			tv.setText(wifi.getFrequency() + "");
			tv = (TextView) (view.findViewById(R.id.txt_signal));
			tv.setText(wifi.getLevel() + "");
			
			SignalView signalView = (SignalView)view.findViewById(R.id.img_sigal);
			signalView.setSignal(wifi.getLevel());

		}

		return view;
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		if (groupPosition == 0) {
			return 1;
		} else if(groupPosition == 1) {
			return 0;
		} else if (groupPosition == 2) {
			return sameFrequencyInterference.size();
		} else if (groupPosition == 3) {
			return nearbyFrequencyInterference.size();
		}
		
		return 0;
	}

	@Override
	public Object getGroup(int groupPosition) {
		if (groupPosition == 0) {
			return "当前AP无线配置";
		} else if(groupPosition == 1) {
			return "干扰图";
		} else if (groupPosition == 2) {
			return "同频干扰";
		} else if (groupPosition == 3) {
			return "邻频干扰";
		}
		
		return "";
	}

	@Override
	public int getGroupCount() {
		return 4;
	}

	@Override
	public long getGroupId(int groupPosition) {
		return groupPosition;
	}

	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		if(groupPosition == 1) {
			return chartContainerView;
		} else {
			View view = convertView;
			if (view == null) {
				view = mInflater.inflate(R.layout.wirelessevngroup, null);
			}
			
			TextView grpName = (TextView) view.findViewById(R.id._grpname);
			Object groupObject = getGroup(groupPosition);
			if(groupObject != null && grpName != null) {
				grpName.setText(groupObject.toString());
			}
			
	        ImageView groupIndicator = (ImageView) view.findViewById(R.id.group_indicator);
	        if(!isExpanded) {
	        	groupIndicator.setImageResource(R.drawable.icon_close);
	        } else {
	        	groupIndicator.setImageResource(R.drawable.icon_open);
	        }
	        
			return view;
		}
	}

	@Override
	public int getGroupType(int groupPosition) {
		if(groupPosition == 1) {
			return 1;
		} else {
			return 0;
		}
	}

	@Override
	public int getGroupTypeCount() {
		return 2;
	}

	@Override
	public boolean hasStableIds() {
		return true;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return false;
	}
	
	protected View initGraphicView() {
		View view = mInflater.inflate(R.layout.wirelesssavebutton, null);
		LinearLayout layout = (LinearLayout) view.findViewById(R.id.wirelessEnvChartPlaceHolder);
		dataset = new XYMultipleSeriesDataset();
		
		renderer.setShowGridX(true);
		renderer.setXAxisMax(100);
		renderer.setXAxisMin(0);
		renderer.setShowGrid(true);
		renderer.setShowAxes(true);
		renderer.setYAxisMax(110);
		renderer.setYAxisMin(0);
		renderer.setPanEnabled(true, false);
		renderer.setZoomEnabled(false);
		renderer.setShowLabels(true);
		renderer.setShowLegend(false);
		renderer.setXTitle("信道");
		renderer.setYTitle("dbm");
		renderer.setFitLegend(true);
		renderer.setGridColor(Color.DKGRAY);
		renderer.setMarginsColor(Color.argb(0, 0xff, 0, 0));
		renderer.setBackgroundColor(Color.TRANSPARENT); // 设置背景色透明
		renderer.setApplyBackgroundColor(true); // 使背景色生效
		renderer.setPanEnabled(false, false);
		renderer.setShowLegend(true);
		renderer.setInScroll(true);
		
		int xxOffset = 2401;
		for(int i =0 ; i < NetworkUtils.channels.length; i++) {
			renderer.addXTextLabel(NetworkUtils.channels[i] - xxOffset, i+1 + "");
		}
		
		renderer.addYTextLabel(50, "-50dbm");
		renderer.addYTextLabel(100, "-100dbm");
		
		chartView = ChartFactory.getTimeChartView(context, dataset, renderer, "");
		chartView.setClickable(false);
		layout.addView(chartView, new LayoutParams(LayoutParams.FILL_PARENT,
				LayoutParams.FILL_PARENT));
		
		layout.requestLayout();
		
		return view;
	}

	public void calculateCurve(List<Wifi> wifiList) {
		//抛无线的三个点(x0, 0), (x1, y1), (x2, 0)，解出抛物线的a，b，c的参数
		//抛无线方程 y = a*x*x + b*x + c;
		//坐标原点(2401, 0) 
		
		List<Wifi> wifis = new ArrayList<Wifi>();
		wifis.addAll(wifiList);
		
		//排序，dbm高的在前
		Collections.sort(wifis, new Comparator<Wifi>(){
			@Override
			public int compare(Wifi lhs, Wifi rhs) {
				if(Math.abs(lhs.getLevel()) <= Math.abs(rhs.getLevel())) {
					return 1;
				} 
				return -1;
			}
		});
		
		int xxOffset = 2401, frequecyBandWidth = 11;
		int xySeriresCount = 0;
		
		//clear render and xySerires
		dataset.clearSerires();
		renderer.clearSeriesRenderers();
			
		for(Wifi wifi : wifis) {
			//计算三个点的坐标
			if(xySeriresCount >= 31)break;
			int y1 = -wifi.getLevel();
			int x1 = wifi.getFrequency() -  xxOffset;
			
			int x0 = wifi.getFrequency()  - xxOffset - frequecyBandWidth;
			int y0 = 0;
			
			int x2 = wifi.getFrequency() - xxOffset + frequecyBandWidth;
			int y2 = 0;
			
			if(y1 == 0)
				continue;
			
			//得出方程组
			double[][] a = { { x0*x0, x0, 1 }, { x1*x1, x1, 1 }, { x2*x2, x2, 1 } };
			double[] b = { y0, y1, y2 };
			double[] x = { 0, 0, 0 };
			
			//计算 抛物线 的三个常数
			// GaussArithmetic.GaussEliminate(a, b, x);
			x = GaussArithmetic.lsolve(a, b);
			
			//Log.d("test", String.format("a=%f b=%f c=%f",  x[0], x[1], x[2]));
			
			XYSeries xySerires = new XYSeries(wifi.getSSID());
			
			//生成点
			int xc;
			double yc;
			for(xc= x0; xc <= x2; xc++) {
				yc = x[0]*xc*xc + x[1]*xc + x[2];
				xySerires.add(xc, yc);
			}
			
			dataset.addSeries(xySerires);
			XYSeriesRenderer r = new XYSeriesRenderer();
			System.err.println("-----------testMessage:"+"wifis:"+wifis.size()+"xySeriresCount:"+xySeriresCount+"ColorUtils.Colors.size:+"+ColorUtils.Colors.size());
			int color = 0;
			if(xySeriresCount >= 31 ){
				xySeriresCount = xySeriresCount % 31;
			}
				color = ColorUtils.Colors.get(xySeriresCount);
			
			//r.setFillBelowLine(true);
			
			//Log.d("test", Math.abs(wifi.getLevel()) + "");
			
			if(wifi.isSelected() == true) {
				r.setFillBelowLineColor(Color.GREEN);
				r.setColor(Color.GREEN);
			} else {
				r.setFillBelowLineColor(Color.rgb(ColorUtils.red(color), ColorUtils.green(color), ColorUtils.blud(color)));
				r.setColor(Color.rgb(ColorUtils.red(color), ColorUtils.green(color), ColorUtils.blud(color)));
			}
			
			r.setPointStyle(PointStyle.POINT);
			
			renderer.addSeriesRenderer(xySeriresCount, r);
			
			if(xySeriresCount < ColorUtils.Colors.size()){
				xySeriresCount++;
			}
			else {
				xySeriresCount = xySeriresCount  % (ColorUtils.Colors.size());
			}
			
			
		}
		
		chartView.invalidate();
	}

	public void setWirelessEvnInfo(WirelessEvnInfo wirelessEvnIfno) {
		this.wirelessEvnInfo = wirelessEvnIfno;
		notifyDataSetChanged();
	}	
}
